/**
 * System Manager
 */
var SYSTEM_MANAGER = "SystemManager";
var SYSTEM_MANAGER_VERSION = "0.3";
var theSystemManager = null;

function SystemManager() {
	this.systems = [];
	this.size = {};
}

function storeSystemManager(sm) {
	console.log("StoreSystemManager");
	var data = {
		version: SYSTEM_MANAGER_VERSION,
		systems: [],
		size: sm.size,
	};
	for (s in sm.systems) {
		var system = sm.systems[s];
		data.systems.push({
			id:        system.id,
			i:         system.i,
			j:         system.j,
			x:         system.x,
			y:         system.y,
			player:    system.player,
			force:     system.force,
			factories: system.factories,
			target:    system.target,
		});
		data.size = sm.size;
	}
	LocalStorage.set(SYSTEM_MANAGER, JSON.stringify(data));
}
function loadSystemManager() {
	var sm = new SystemManager();

	var data = JSON.parse(LocalStorage.get(SYSTEM_MANAGER));
	if (data.version != SYSTEM_MANAGER_VERSION) {
		LocalStorage.del(SYSTEM_MANAGER);
		throw "SystemManager is wrong version!";
	}
	sm.systems = data.systems;
	sm.size = data.size;

	return sm;
}

function getSystemManager() {
	if (!theSystemManager) {
		if (LocalStorage.has(SYSTEM_MANAGER)) {
			theSystemManager = loadSystemManager();
		} else {
			theSystemManager = new SystemManager();
//			storeSystemManager(theSystemManager);
		}
	}
	return theSystemManager;
}

SystemManager.prototype.store = function() {
	console.log("StoreSystemManager");
	storeSystemManager(this);
}

SystemManager.prototype.clearSystems = function() {
	this.systems = [];
	this.size = {};

//	storeSystemManager(this);
}
SystemManager.prototype.addSystem = function(system) {
	this.systems.push(system);

	if (!this.size.minx || this.size.minx > system.x) this.size.minx = system.x;
	if (!this.size.maxx || this.size.maxx < system.x) this.size.maxx = system.x;
	if (!this.size.miny || this.size.miny > system.y) this.size.miny = system.y;
	if (!this.size.maxy || this.size.maxy < system.y) this.size.maxy = system.y;

//	storeSystemManager(this);
}
SystemManager.prototype.getSystem = function(filter) {
	var result = null;
	for (var s in this.systems) {
		var system = this.systems[s];
		if (typeof filter == "function" && filter(system)) {
			result = system;
			break;
		}

		if (typeof filter == "object") {
			var isOk = true;
			for (var key in filter) {
				if (filter[key] != system[key]) {
					isOk = false;
					break;
				}
			}
			if (isOk) {
				result = system;
				break;
			}
		}
	}
	return result;
}
SystemManager.prototype.getSystems = function(filter) {
	var result = [];
	for (var s in this.systems) {
		var system = this.systems[s];
		if (typeof filter == "function" && filter(system)) {
			result.push(system);
		}

		if (typeof filter == "object") {
			var isOk = true;
			for (var key in filter) {
				if (filter[key] != system[key]) {
					isOk = false;
					break;
				}
			}
			if (isOk) {
				result.push(system);
			}
		}
	}
	return result;
}

var TestSystemManager = {};

TestSystemManager.testClearSystems = function() {
	var sm = new SystemManager();

	sm.systems = [{}];
	assertEqual(sm.systems.length, 1, "TestClearSystems 1");

	sm.clearSystems();
	assertEqual(sm.systems.length, 0, "TestClearSystems 2");
}
TestSystemManager.testAddSystem = function() {
	var sm = new SystemManager();

	assertEqual(sm.systems.length, 0);

	assertUndefined(sm.addSystem({id:null}), "testAddSystem 1");
	assertUndefined(sm.addSystem({id:"s0", x:5}), "testAddSystem 2");
	assertUndefined(sm.addSystem({id:"s0"}), "testAddSystem 3");
	assertUndefined(sm.addSystem({id:"s0", x:10}), "testAddSystem 4");

	assertEqual(sm.systems.length, 4);

	assertEqual(sm.size.minx, 5, "TestAddSystem 5");
	assertEqual(sm.size.maxx, 10, "TestAddSystem 6");
}
TestSystemManager.testGetSystem = function() {
	var sm = new SystemManager();
	sm.systems.push({id:"id0", x:-1});
	sm.systems.push({id:"id1", x: 0});
	sm.systems.push({id:"id2", x: 1});

	assertEqual(sm.getSystem({id: "id1"}).x, 0, "testGetSystem 1");
	assertEqual(sm.getSystem(function(system) {return system.x > 0;}).id, "id2", "testGetSystem 2");
}
TestSystemManager.testGetSystems = function() {
	var sm = new SystemManager();
	sm.systems.push({id:"id0", x:-1, player:"p0"});
	sm.systems.push({id:"id1", x: 0, player:"p1"});
	sm.systems.push({id:"id2", x: 1, player:"p1"});

	assertEqual(sm.getSystems({player: "p1"}).length, 2, "testGetSystems 1");
	assertEqual(sm.getSystems(function(system) {return system.x >= 0;}).length, 2, "testGetSystems 2");
}

TestSystemManager.test = function() {
	try {
		this.testClearSystems();
		this.testAddSystem();
		this.testGetSystem();
		this.testGetSystems();
	} catch(e) {
		console.error(e);
	}
}
